home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / src / WBBump_src.lha / WBBump_src / bumper.e < prev    next >
Encoding:
Text File  |  1999-06-30  |  6.9 KB  |  342 lines

  1. /* ******** */
  2. /* bumper.e */
  3. /* ******** */
  4.  
  5.  
  6.  
  7. /*
  8.     WBBump - Bumpmapping on the Workbench!
  9.  
  10.     Copyright (C) 1999  Thomas Jensen - dm98411@edb.tietgen.dk
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License, or
  15.     (at your option) any later version.
  16.  
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.  
  22.     You should have received a copy of the GNU General Public License
  23.     along with this program; if not, write to the Free Software Foundation,
  24.     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. */
  26.  
  27.  
  28.  
  29. OPT MODULE
  30.  
  31.  
  32. MODULE    'intuition/intuition',        -> window
  33.         'intuition/screens',        -> screen
  34.         'intuition/intuitionbase',    -> intuitionbase
  35.  
  36.         'graphics/gfx',                -> bitmap
  37.         'graphics/rastport',        -> screen.rastport.bitmap
  38.         'graphics/view',            -> screen.viewport.colormap
  39.  
  40.         'exec/nodes',
  41.         'exec/lists'
  42.  
  43.  
  44. MODULE    '*prefs',
  45.         '*chunkyimage',
  46.         '*errors',
  47.         '*plugin',
  48.         '*pluginmanager'
  49.  
  50.  
  51. /* "template" bumper def */
  52. EXPORT OBJECT bumper
  53.     win            :    PTR TO window
  54.     width       :    INT
  55.     height      :    INT
  56.     backup       :    PTR TO cimg        -> backup of hidden area of screen (allocated by bumper_xxx)
  57.     blut        :    PTR TO CHAR        -> brightness lookup table (may be null)
  58.     cusage        :    PTR TO CHAR        -> color usage array [256], cusage[x] = 0 if color x is not used
  59.                                     -> must be supplied by bumper_xxx.make_backup if .make_blut in
  60.                                     -> this file is used
  61.     levels      :    INT                -> levels in above
  62.     levels_bit  :   CHAR
  63.     prefs        :    PTR TO prefs    -> pointer to prefs structure used to create this bumper
  64.     plugins        :    PTR TO pluginlist    -> all the plugins in here
  65.     oldlx        :    LONG
  66.     oldly        :    LONG
  67. ENDOBJECT
  68.  
  69.  
  70.  
  71. /* constructor */
  72. PROC bumper(p:PTR TO prefs, plist:PTR TO pluginlist) OF bumper HANDLE
  73.     DEF    s:PTR TO screen,
  74.         tempstr[1024]:STRING,
  75.         px, py
  76.  
  77.  
  78.     /* init local prefs pointer */
  79.  
  80.     self.prefs := p
  81.  
  82.  
  83.  
  84.     /* init vars */
  85.     self.win := NIL
  86.     self.backup := NIL
  87.     self.blut := NIL
  88.     self.plugins := NIL
  89.  
  90.     self.levels := p.levels
  91.     self.levels_bit := p.levels_bit
  92.  
  93.  
  94.     /* set initial light position out of screen */
  95.  
  96.     self.oldlx := -1
  97.     self.oldly := -1
  98.  
  99.  
  100.  
  101.     /* load the plugins */
  102.  
  103.     NEW self.plugins.pluginlist()
  104.  
  105.  
  106.     /* load from tooltypes */
  107.     IF p.tooltypes
  108.         self.plugins.addInstancesTT(p.tooltypes, plist)
  109.     ENDIF
  110.  
  111.     /* if no loaded yet, try with the file of the activated icon */
  112.     IF self.plugins.isEmpty()
  113.         self.plugins.addInstancesTT([StringF(tempstr, 'BUMPMAP=\s', p.fullprjname), 0], plist, FALSE)
  114.     ENDIF
  115.  
  116.     /* still no? - try default bumpmap */
  117.     IF self.plugins.isEmpty()
  118.         self.plugins.addInstancesTT(['BUMPMAP=PROGDIR:Bumpmaps/Amiga.ilbm', 0], plist)
  119.     ENDIF
  120.  
  121.  
  122.     p.width        := self.plugins.getFirstWidth()
  123.     p.height    := self.plugins.getFirstHeight()
  124.     self.width    := p.width
  125.     self.height    := p.height
  126.  
  127.  
  128.     /* lock the public screen */
  129.     s := LockPubScreen(p.scrname)
  130.     IF s = NIL THEN eThrow(ERR_LOCKSCR, 'Uanble to lock public screen: "%s"', [p.scrname])
  131.  
  132.  
  133.     /* set or calc position */
  134.     px := p.posx
  135.     py := p.posy
  136.  
  137.     IF px = POS_CENTER THEN px := (s.width - self.width) / 2
  138.     IF py = POS_CENTER THEN py := (s.height - self.height) / 2
  139.  
  140.  
  141.     /* make backup image */
  142.     self.make_backup(s, px, py)
  143.  
  144.  
  145.  
  146.     /* open the window */
  147.     self.win := OpenWindowTagList(NIL, [
  148.         WA_GIMMEZEROZERO, TRUE,
  149.         WA_INNERWIDTH, self.width,
  150.         WA_INNERHEIGHT, self.height,
  151.         WA_LEFT, px,
  152.         WA_TOP, py,
  153.         WA_BORDERLESS, TRUE,
  154.         WA_DRAGBAR, FALSE,
  155.         WA_BACKDROP, TRUE,
  156.         WA_PUBSCREEN, s,
  157.         NIL])
  158.     IF self.win = NIL THEN Raise(ERR_OPENWINDOW)
  159.  
  160.  
  161.     /* blit backup bitmap to window rastport */
  162.  
  163. ->    self.backup.write_full(self.win.rport, 0, 0)
  164.  
  165.  
  166.     /* create blut (if nessesary) */
  167.     self.make_blut(s)
  168.  
  169.  
  170. EXCEPT DO
  171.     IF s THEN UnlockPubScreen(NIL, s)
  172.     IF exception
  173.         self.freeall()
  174.     ENDIF
  175.     ReThrow()
  176. ENDPROC
  177.  
  178.  
  179.  
  180. /* should be overloaded (if nessesary) */
  181. PROC make_blut(s:PTR TO screen) OF bumper HANDLE
  182.     DEF    i, j,
  183.         b=NIL:PTR TO CHAR,
  184.         scol[1024]:ARRAY OF LONG,
  185.         colors,
  186.         or, og, ob,
  187.         nr, ng, nb
  188.  
  189.  
  190.     self.blut := NewR(self.levels * 256)
  191.  
  192.     b := self.blut
  193.  
  194.     colors := Shl(1, s.rastport.bitmap.depth)
  195.     GetRGB32(s.viewport.colormap, 0, colors-1, scol)
  196. /*
  197.     WriteF('colors: \d\n', colors)
  198.     WriteF('Colors:\n')
  199.     FOR i := 0 TO colors-1
  200.         WriteF('\d[3]: $\h[8], $\h[8], $\h[8]\n', i, scol[i*4], scol[i*4+1], scol[i*4+2])
  201.     ENDFOR
  202. */
  203.     FOR i := 0 TO colors-1
  204.  
  205.         IF (self.cusage[i])    -> only if color is actually used
  206.  
  207.             or := And(Shr(scol[(i*3)+0], 24), $FF)
  208.             og := And(Shr(scol[(i*3)+1], 24), $FF)
  209.             ob := And(Shr(scol[(i*3)+2], 24), $FF)
  210.  
  211.             FOR j := 0 TO self.levels-1
  212.                 nr := Shl(calc_color(or, self.prefs.lightr, j, self.levels-1), 24)
  213.                 ng := Shl(calc_color(og, self.prefs.lightg, j, self.levels-1), 24)
  214.                 nb := Shl(calc_color(ob, self.prefs.lightb, j, self.levels-1), 24)
  215.                 b[Shl(j, 8) + i] := ObtainBestPenA(s.viewport.colormap, nr, ng, nb, [OBP_PRECISION, PRECISION_EXACT, OBP_FAILIFBAD, FALSE, NIL])
  216. ->                WriteF('\d[3], \d[3]: $\h[8], $\h[8], $\h[8] (\d)\n', i, j, nr, ng, nb, b[Shl(j, 8) + i])
  217.             ENDFOR
  218.  
  219.         ENDIF
  220.  
  221.     ENDFOR
  222.  
  223. EXCEPT DO
  224.     ReThrow()
  225. ENDPROC
  226.  
  227.  
  228.  
  229. PROC calc_color(val, lightcol, lev, maxlev) IS calc_color3(val, lightcol, lev, maxlev)
  230.  
  231.  
  232. /* black -> white */
  233. PROC calc_color2(val, lev, maxlev)
  234.     DEF    temp,
  235.         ml2, ml21
  236.  
  237.     ml2 := maxlev/2
  238.     ml21 := ml2 - 1
  239.  
  240.     IF lev < ml2
  241.         RETURN (val * lev) / ml2
  242.     ELSE
  243.         lev := lev - ml2
  244.         temp := val + (Shl(lev, 8) / ml2)
  245.         IF temp > 255 THEN RETURN 255
  246.         IF temp < 0 THEN RETURN 0
  247.     ENDIF
  248. ENDPROC temp
  249.  
  250.  
  251. /* original -> white */
  252. PROC calc_color3(val, lightcol, lev, maxlev)
  253.     DEF    temp
  254.  
  255.     temp := val + Shr(Mul((Shl(lev, 8) / maxlev), lightcol), 8)
  256.     IF temp > 255 THEN RETURN 255
  257.     IF temp < 0 THEN RETURN 0
  258.  
  259. ENDPROC temp
  260.  
  261.  
  262.  
  263. /* should be overloaded */
  264. PROC make_backup(s:PTR TO screen, px, py) OF bumper HANDLE
  265.  
  266.     /* allocate backup bitmap */
  267.     NEW self.backup.alloc(self.width, self.height, CIMGTYP_8BIT)
  268.  
  269.     self.backup.read_full(s.rastport, px, py)
  270.  
  271. EXCEPT DO
  272.     ReThrow()
  273. ENDPROC
  274.  
  275.  
  276.  
  277.  
  278. /* stub functions that MUST be overloaded */
  279.  
  280. PROC update() OF bumper IS Throw(ERR_INTERNAL, 'Function not implemented')
  281.  
  282.  
  283.  
  284.  
  285. /* in an update needed? */
  286.  
  287. PROC needUpdate() OF bumper
  288.     DEF    ibase=NIL:PTR TO intuitionbase,
  289.         lightx, lighty
  290.  
  291.     /* check if screen is the active one */
  292.  
  293.     ibase := intuitionbase
  294.     IF self.win.wscreen <> ibase.firstscreen THEN RETURN FALSE
  295.  
  296.  
  297.     /* light position */
  298.  
  299.     lightx, lighty := self.getLightSourcePos()
  300.  
  301.     IF (self.oldlx <> lightx) OR (self.oldly <> lighty)
  302.         self.oldlx := lightx
  303.         self.oldly := lighty
  304.         RETURN TRUE
  305.     ENDIF
  306.  
  307.  
  308.     /* does plugins need update? */
  309.  
  310.     IF self.plugins.needUpdate() THEN RETURN TRUE
  311.  
  312. ENDPROC FALSE
  313.  
  314.  
  315.  
  316.  
  317. PROC getLightSourcePos() OF bumper
  318. ENDPROC MouseX(self.win), MouseY(self.win)
  319.  
  320.  
  321.  
  322. PROC freeall() OF bumper
  323.     IF self.win THEN CloseWindow(self.win)
  324.     IF self.blut THEN Dispose(self.blut)
  325.     END self.backup
  326.     END self.plugins
  327.     self.win := NIL
  328.     self.blut := NIL
  329.     self.backup := NIL
  330. ENDPROC
  331.  
  332.  
  333.  
  334. PROC end() OF bumper
  335.     self.freeall()
  336. ENDPROC
  337.  
  338.  
  339.  
  340.  
  341.  
  342.